package com.mm.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {

	/**
	 * 时刻：所有计算机系统内部都用一个整数表示时刻，这个整数是距离格林尼治标准时间1970年1月1日0时0分0秒的毫秒数，可以理解时刻就是绝对时间，它与时区无关，不同时区对同一时刻的解读，即年月日时分秒是不一样的；
	 * 
	 * 时区：同一时刻，世界上各个地区的时间可能是不一样的，具体时间与时区有关，一共有24个时区，英国格林尼治是0时区，北京是东八区，也就是说格林尼治凌晨1点，北京是早上9点；
	 * 
	 * 年历：我们都知道，中国有公历和农历之分，公历和农历都是年历，不同的年历，一年有多少月，每月有多少天，甚至一天有多少小时，这些可能都是不一样的，我们主要讨论公历。
	 * Instant：它代表的是时间戳，表示时刻，不直接对应年月日信息，需要通过时区转换
	 * 
	 * LocalDateTime: 表示与时区无关的日期和时间信息，不直接对应时刻，需要通过时区转换
	 * 
	 * LocalDate：表示与时区无关的日期，与LocalDateTime相比，只有日期信息，没有时间信息
	 * 
	 * LocalTime：表示与时区无关的时间，与LocalDateTime相比，只有时间信息，没有日期信息
	 * 
	 * ZonedDateTime： 表示特定时区的日期和时间
	 * 
	 * ZoneId/ZoneOffset：表示时区
	 */

	public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

//	private static final String DATETIME_FORMATTER_STRING = "yyyy-MM-dd HH:mm:ss";
//	private static final String DATE_FORMAT_STRING = "yyyy-MM-dd";

	/**
	 * 返回当前的日期LocalDate格式
	 * 
	 * @return
	 */
	public static LocalDate getCurrentLocalDate() {
		return LocalDate.now();
	}

	/**
	 * 返回当前日期时间LocalDateTime格式
	 * 
	 * @return
	 */
	public static LocalDateTime getCurrentLocalDateTime() {
		return LocalDateTime.now();
	}

	/**
	 * 返回当前日期字符串 yyyyMMdd
	 * 
	 * @return
	 */
	public static String getCurrentDateStr() {
		return LocalDate.now().format(DATE_FORMATTER);
	}

	/**
	 * 返回当前日期时间字符串 yyyyMMddHHmmss
	 * 
	 * @return
	 */
	public static String getCurrentDateTimeStr() {
		return LocalDateTime.now().format(DATETIME_FORMATTER);
	}

	public static LocalDate parseLocalDate(String dateStr, String pattern) {
		return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
	}

	public static LocalDateTime parseLocalDateTime(String dateTimeStr, String pattern) {
		return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 日期相隔天数（两个LocalDate类型的日期）
	 * 
	 * @param startDateInclusive
	 * @param endDateExclusive
	 * @return
	 */
	public static int periodDays(LocalDate startDateInclusive, LocalDate endDateExclusive) {
		return Period.between(startDateInclusive, endDateExclusive).getDays();
	}

	/**
	 * 日期相隔小时
	 * 
	 * @param startInclusive
	 * @param endExclusive
	 * @return
	 */
	public static long durationHours(Temporal startInclusive, Temporal endExclusive) {
		return Duration.between(startInclusive, endExclusive).toHours();
	}

	/**
	 * 日期相隔分钟
	 * 
	 * @param startInclusive
	 * @param endExclusive
	 * @return
	 */
	public static long durationMinutes(Temporal startInclusive, Temporal endExclusive) {
		return Duration.between(startInclusive, endExclusive).toMillis();
	}

	/**
	 * 日期相隔毫秒数
	 * 
	 * @param startInclusive
	 * @param endExclusive
	 * @return
	 */
	public static long durationMillis(Temporal startInclusive, Temporal endExclusive) {
		return Duration.between(startInclusive, endExclusive).toMillis();
	}

	/**
	 * 传入时间戳，返回String格式化日期
	 * 
	 * @param timeStamp
	 * @return
	 */
	public static String timeStampToDate(long timeStamp) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String format = sf.format(timeStamp);
		return format;
	}

	/**
	 * 传入String格式时间，返回时间戳
	 * 
	 * @param dateTime
	 * @return
	 */
	public static long dateToTimeStamp(String dateTime) {
		try {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date = sf.parse(dateTime);
			long date2 = date.getTime();
			long valueOf = Long.parseLong(String.valueOf(date2));
			return valueOf;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * 传入String格式时间，返回时间戳
	 * 
	 * @Title: dateToTimeStampYear
	 * @Description: TODO(描述)
	 * @param dateTime
	 * @return
	 * @author author
	 * @date 2020-03-12 09:01:26
	 */
	public static long dateToTimeStampYear(String dateTime) {
		try {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy");
			Date date = sf.parse(dateTime);
			long date2 = date.getTime();
			long valueOf = Long.parseLong(String.valueOf(date2));
			return valueOf;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return 0;
	}

	public static long dateToTimeStampNotSecond(String dateTime) {
		try {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			Date date = sf.parse(dateTime);
			long date2 = date.getTime();
			long valueOf = Long.parseLong(String.valueOf(date2));
			return valueOf;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return 0;
	}

	/**
	 * 将localDate 按照一定的格式转换成String
	 * 
	 * @param localDate
	 * @param pattern
	 * @return
	 */
	public static String localDateFormat(LocalDate localDate, String pattern) {
		return localDate.format(DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 将localDateTime 按照一定的格式转换成String
	 * 
	 * @param localDateTime
	 * @param pattern
	 * @return
	 */
	public static String localDateTimeFormat(LocalDateTime localDateTime, String pattern) {
		return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 将String 按照pattern 转换成LocalDate
	 * 
	 * @param time
	 * @param pattern
	 * @return
	 */
	public static LocalDate localDateParse(String time, String pattern) {
		return LocalDate.parse(time, DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 将String 按照pattern 转换成LocalDateTime
	 * 
	 * @param time
	 * @param pattern
	 * @return
	 */
	public static LocalDateTime localDateTimeParse(String time, String pattern) {
		return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * Date类型的日期转为LocalDate类型的日期
	 * 
	 * @param date
	 * @return LocalDate
	 */
	public static LocalDate dateToLocalDate(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
	}

	/**
	 * Date类型的日期转为LocalDateTime类型的日期
	 * 
	 * @param date
	 * @return LocalDateTime
	 */
	public static LocalDateTime dateToLocalDateTime(Date date) {
		return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
	}

	/**
	 * LocalDate类型的日期转为Date类型的日期
	 * 
	 * @param localDate
	 * @return Date
	 */
	public static Date localDateToDate(LocalDate localDate) {
		return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
	}

	/**
	 * LocalDateTime类型的日期转为Date类型的日期
	 * 
	 * @param localDateTime
	 * @return Date
	 */
	public static Date localDateTimeToDate(LocalDateTime localDateTime) {
		return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
	}

	/**
	 * Date类型的日期往后推N天
	 * 
	 * @param date
	 * @param number
	 * @return
	 */
	public static Date plusDate(Date date, int number) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, number);// 把日期往后增加N天.正数往后推,负数往前推
		date = calendar.getTime(); // 这个时间就是日期往后推N天的结果
		return date;
	}

	/**
	 * 获取当天的零点时间戳
	 *
	 * @return 当天的零点时间戳
	 */
	public static long getTodayStartTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime().getTime();
	}

}
